package com.zqs.compareface.utils.impl;
/**
 * 两个向量可以为任意维度，但必须保持维度相同，表示n维度中的两点
 *  欧式距离
 * @param
 * @param
 * @return 两点间距离
 */

public class EuclideanDistance {
    /**
     * 一对一，两个点之间的欧式距离计算
     * @param vector1
     * @param vector2
     */
    public void sim_distance(double[] vector1 ,double[] vector2){
        double distance = 0;
        if (vector1.length == vector2.length) {
            for (int i = 0; i < vector1.length; i++) {
                double temp = Math.pow((vector1[i] - vector2[i]), 2.0);
                distance += temp;
            }
            distance = Math.sqrt(distance);
        }
        System.out.println("single欧氏距离"+distance);
    }

    /**
     * 向量a与矩阵的欧式距离
     * @param vector1
     * @param vector2
     */
    public void jsim_distance(double[] vector1, double[][] vector2) {
        double distance[]= new double[vector2.length];
        if (vector1.length == vector2[0].length) {
            for (int i = 0; i < vector1.length; i++) {
                for(int j=0; j < vector2.length; j++){
                    try {
                        distance[j] += Math.pow((vector1[i] - vector2[j][i]), 2.0);
                    }catch (ArrayIndexOutOfBoundsException e){
                        e.printStackTrace();
                    }
                }  }}
        for (int i = 0; i < distance.length; i++) {
            distance[i] = Math.sqrt(distance[i]); }

        for(int i=0;i< distance.length;i++){
            System.out.println("质心计算" + distance[i]);}
    }

    /**
     * 标准欧式距离计算
     * @param vector1
     * @param vector2
     */
    public void standerd_distance(double[] vector1, double[][] vector2) {
        double[] s = new double[vector2.length + 1];
        double[] avg = new double[vector2.length];
        // vector2均值
        for (int i = 0; i < vector2.length; i++) {
            for (int j = 0; j < vector2[0].length; j++) {
                avg[i] += vector2[i][j];
            }
        }
        // vector1均值
        double avg0 = 0;
        for (int i = 0; i < vector1.length; i++) {
            avg0 += vector1[i];
        }
        //vector1方差
        if (vector1.length == vector2[0].length) {
            for (int i = 0; i < vector1.length; i++) {
                s[0] += Math.pow(vector1[i] - avg0, 2);
            }
            s[0] = Math.sqrt(s[0] / vector2.length);
        }
        //vector2方差
        for (int i = 0; i < vector2.length; i++) {
            for (int j = 0; j < vector2[0].length; j++) {
                s[i + 1] += Math.pow(vector2[i][j] - avg[i], 2);
            }
            s[i + 1] = Math.sqrt(s[i] / vector2.length);
        }

        //标准化欧氏距离
        double distance[] = new double[vector2.length];
        for (int i = 0; i < vector1.length; i++) {
            for (int j = 0; j < vector2.length; j++) {
                double temp = Math.pow((vector1[i] - vector2[j][i]), 2) / s[i];
                distance[j] = distance[j] + temp;
            }
        }
        for (int i = 0; i < distance.length; i++) {
            distance[i] = Math.sqrt(distance[i]);
        }
        for (int i = 0; i < distance.length; i++) {
            System.out.println(distance[i]);
        }
    }

    public static void main(String[] args){
        System.out.println("普通欧氏距离");
        EuclideanDistance s1=new EuclideanDistance();
        double[]a={5,5,1};
        double[]b={1,2,1};
        s1.sim_distance(a,b);
        System    .out.println("矩阵欧氏距离");
        //向量a与矩阵的欧式距离
        double[][]c={{1,5,1},{2,7,1},{1,1,1}};
        s1.jsim_distance(a,c);
        //向量a与矩阵的标准欧式距离
        System.out.println("标准欧氏距离");
        s1.standerd_distance(a,c);
    }
}
